import java.io.*;
import java.net.*;
import java.util.HashSet;
import java.util.Set;

public class ReliableUDPServer {
    private static final int PACKET_SIZE = 1024;
    private static final int WINDOW_SIZE = 3;

    public static void main(String[] args) {
        DatagramSocket serverSocket = null;
        Set<Integer> set = new HashSet<>();
        try {
            serverSocket = new DatagramSocket(9876);
            serverSocket.setSoTimeout(5000);

            while (true) {
                byte[] receiveData = new byte[PACKET_SIZE];
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

                try {
                    serverSocket.receive(receivePacket);
                } catch (SocketTimeoutException e) {
                    System.out.println("发生超时。正在等待下一个数据包...");
                    continue;
                }

                int sequenceNumber = receiveData[0];
                byte[] fileData = new byte[receivePacket.getLength() - 1];
                System.arraycopy(receiveData, 1, fileData, 0, fileData.length);

                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();

                System.out.println("从客户端收到 (序列为： " + sequenceNumber + ")");

                // Simulate processing
                String response = "ACK: " + sequenceNumber;
                byte[] sendData = response.getBytes();

                // 发送确认
                DatagramPacket ackPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);

                serverSocket.send(ackPacket);

                // 处理接收到的数据 (e.g., write to a file)
                if(!set.contains(sequenceNumber)) {
                    processReceivedData(fileData);
                } else {
                    set.add(sequenceNumber);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        }
    }

    private static void processReceivedData(byte[] data) throws IOException {
        // Implement the logic to handle the received data, e.g., write to a file
        try (FileOutputStream fos = new FileOutputStream("D:/456.txt",true) ){
            fos.write(data);
        }
    }
}

